#from sls_uavPPDialog import Ui_UAVPPDialog
from sls_uavPPDialog import Ui_UAVPPDialog
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QPushButton, QLineEdit, QListWidget, 
                            QLabel, QMessageBox,QDialog, QMenu)
from sls_mirrors import sls_agent
from PyQt6.QtCore import Qt
import path_planner1
import json
import os
import time

mission_table={"MissionsEBLOSSteering","MissionsDroneGsta",}
uav_ugv_table={"uav1","uav2",}
planners_table = {"Planner1": 0,
                "Planner2": 1,}

class UAVPPDialog(QDialog):
    def __init__(self, parent, menu:QMenu):
        super().__init__(parent)
        self.id = id
        self.parent = parent
        self.menu = menu
        self.parent.ui.uavPathPlan.setEnabled(False)
        self.parent.ui.ugvPathPlan.setEnabled(False)
        self.parent.ui.tools.setEnabled(False)
        # 初始化UI
        self.ui = Ui_UAVPPDialog()
        self.ui.setupUi(self)
        self.setWindowTitle(f"无人机的路径规划")
        
        self.click_points = []
        self.path_points = []
        self.marker_name = []
        self.takeoffDict = {}
        self.init_mission_ui()
        self.init_history_plan_ui()
        self.ui.doubleSpinBox_mission_height.setDisabled(True)
        self.parent.notifyClass.add_notify_Cordinate(self.on_click_point)
        self.ui.pushButton_remove.clicked.connect(self.remove_point)
        self.ui.pushButton_pathplan.clicked.connect(self.show_path)
        self.ui.tabWidget.currentChanged.connect(self.on_tab_changed)  
        self.current_method = "abline" 
        self.ui.comboBox_planners.currentTextChanged.connect(self.switch_page)
        self.ui.pushButton_publish.clicked.connect(self.on_publish)  
        self.ui.pushButton_replan.clicked.connect(self.clearallset)
        self.ui.pushButton_save_path.clicked.connect(self.save_plan_tojson)
        self.ui.pushButton_del_history_path.clicked.connect(self.del_history_plan)
        self.ui.checkBox_isUse_historyPlan.stateChanged.connect(self.use_history_path)
        self.ui.comboBox_history_paths.currentTextChanged.connect(self.show_history_path)
        self.ui.pushButton_use_history_boundary.clicked.connect(self.use_history_boundary)
        self.ui.checkBox_isSet_height.stateChanged.connect(self.set_height)
        
        self.clearallset()

    def switch_page(self):
        # 根据当前文本切换页面
        current_text = self.ui.comboBox_planners.currentText()
        if current_text in planners_table:
            target_index = planners_table[current_text]
            self.ui.stackedWidget.setCurrentIndex(target_index)
            self.clearallset()

    def set_height(self):
        if self.ui.checkBox_isSet_height.checkState() == Qt.CheckState.Unchecked:
            self.ui.doubleSpinBox_mission_height.setDisabled(True)
        elif self.ui.checkBox_isSet_height.checkState() == Qt.CheckState.Checked:
            self.ui.doubleSpinBox_mission_height.setDisabled(False)

    def on_tab_changed(self, index):
        if index == 0:
            self.current_method = "abline"
        elif index == 1:
            self.current_method = "planner"
        self.clearallset()

    def init_mission_ui(self):
        self.ui.comboBox_mission.clear()
        self.ui.comboBox_mission.addItems(sorted(mission_table))
        self.ui.comboBox_uav_ugv.clear()
        self.ui.comboBox_uav_ugv.addItems(sorted(uav_ugv_table))
        self.ui.comboBox_planners.clear()
        self.ui.comboBox_planners.addItems(sorted(planners_table.keys()))

    def init_history_plan_ui(self):
        try:
            with open("pathsfile.json", "r", encoding="utf-8") as file:
                data = json.load(file)
            all_plan_names = [plan_data["plan_name"] for plan_data in data]
        except FileNotFoundError:
            return None
        except json.JSONDecodeError:
            return None
        self.ui.comboBox_history_paths.clear()
        self.ui.comboBox_history_paths.addItems(all_plan_names)
        self.ui.comboBox_history_boundaries.clear()
        self.ui.comboBox_history_boundaries.addItems(all_plan_names)
        
    def use_history_boundary(self):
        self.clearallset()
        plan_name = self.ui.comboBox_history_boundaries.currentText()
        plan_data = self.read_plan_fromjson(plan_name)
        if  plan_data == None:
            self.ui.label_planner_info.setText("该历史任务没有边界数据，请重新选择")
            self.ui.label_planner_info.setStyleSheet("QLabel { color: red; }")
            return
        self.click_points = []
        self.click_points = plan_data["boundary_points"]
        color = "#3010A3"
        boundary_points = [[point[1], point[0]] for point in self.click_points]
        boundary_points.append(boundary_points[0])
        self.parent.del_polyline("boundary" )
        self.parent.add_polyline(boundary_points,color,"boundary" )
        self.ui.label_planner_info.setText("已加载历史任务区域，可以进行路径规划")
        self.ui.label_planner_info.setStyleSheet("QLabel { color: black; }")


    def use_history_path(self):
        self.clearallset()
        if self.ui.checkBox_isUse_historyPlan.checkState() == Qt.CheckState.Unchecked:
            self.parent.del_polyline("history_path" )
            self.parent.del_polyline("history_boundary" )
            self.ui.label_history_path_info.clear()
            return 
        elif self.ui.checkBox_isUse_historyPlan.checkState() == Qt.CheckState.Checked:
            self.ui.label_history_path_info.setText("使用历史路径规划任务")
            self.show_history_path()
            
    
    def remove_point(self):
        if self.click_points: 
            self.click_points.pop()
            if self.marker_name:
                name = self.marker_name.pop()
                self.parent.del_marker(name)
            if self.click_points:
                if self.current_method == "planner":
                    color = "#3010A3"
                    boundary_points = [[point[1], point[0]] for point in self.click_points]
                    boundary_points.append(boundary_points[0])
                    self.parent.del_polyline("boundary" )
                    self.parent.add_polyline(boundary_points,color,"boundary" )
                if self.current_method == "abline":
                    path_points = [[point[1], point[0]] for point in self.click_points]
                    color = "#E20D29"
                    self.parent.del_polyline("planed_path")
                    self.parent.add_polyline(path_points,color,"planed_path")

    
    def on_click_point(self,latitude,longitude):
        self.click_points.append([latitude,longitude])
        if self.current_method == "abline":
            self.marker_name.append(f"path_point*{len(self.click_points)}" )
            self.parent.add_marker(latitude, longitude,f"path_point*{len(self.click_points)}")
            path_points = [[point[1], point[0]] for point in self.click_points]
            self.path_points = [[point[1], point[0]] for point in self.click_points]
            color = "#E20D29"
            self.parent.del_polyline("planed_path")
            self.parent.add_polyline(path_points,color,"planed_path")
            self.ui.label_ok_erro.clear()

        if self.current_method == "planner":
            self.marker_name.append(f"boundary_point*{len(self.click_points)}")
            self.parent.add_marker(latitude, longitude, f"boundary_point*{len(self.click_points)}")
            color = "#3010A3"
            boundary_points = [[point[1], point[0]] for point in self.click_points]
            boundary_points.append(boundary_points[0])
            self.parent.del_polyline("boundary" )
            self.parent.add_polyline(boundary_points, color, "boundary" )
            # self.ui.pushButton_pathplan.setEnabled(len(self.click_points) >= 3)

    def show_path(self):
        if self.ui.stackedWidget.currentIndex() == 0:
            params = {
                "step_size": self.ui.doubleSpinBox_p1_1.value(),
                "offset_distance": self.ui.doubleSpinBox_p1_2.value()
            }
            boundary_points = [[point[1], point[0]] for point in self.click_points]
            self.path_points.clear()
            try:
                # 尝试调用子程序
                self.path_points = path_planner1.generate_coverage_path(params, boundary_points) #lon lat
            except Exception as e:
                self.click_points = []
                self.clearallset()
                self.ui.label_planner_info.clear()
                self.ui.label_planner_info.setText("路径未生成，请重新选择任务区域")
                self.ui.label_planner_info.setStyleSheet("QLabel { color: red; }")
                print(f"规划算法出错: {e}")
                return
            # self.path_points = path_planner1.generate_coverage_path(params, boundary_points) 

        elif self.current_method == "planner2":
            params = [
            self.ui.doubleSpinBox_p2_1.value(),
            self.ui.doubleSpinBox_p2_2.value()
            ]
            # data = path_planner1.planner2(params, self.click_points)
        self.ui.label_ok_erro.clear()
        self.ui.label_planner_info.setText("路径规划成功,如需保存路径请输入路径名：")
        self.ui.label_planner_info.setStyleSheet("QLabel { color: black; }")
        color = "#E20D29"
        self.parent.del_polyline("planed_path")
        self.parent.add_polyline(self.path_points,color,"planed_path")
        self.parent.del_sortedMarkers("boundary_point")
        self.marker_name = []

    def show_history_path(self):
        if self.ui.checkBox_isUse_historyPlan.checkState() == Qt.CheckState.Checked: 
            plan_name = self.ui.comboBox_history_paths.currentText()
            plan_data = self.read_plan_fromjson(plan_name)
            if  plan_data == None:
                return
            self.path_points = plan_data["path_points"]
            boundary_points = [[point[1], point[0]] for point in plan_data["boundary_points"]]
            self.parent.del_polyline("history_path")
            self.parent.del_polyline("history_boundary")
            color = "#E20D29"
            self.parent.add_polyline(self.path_points,color,"history_path")
            color = "#3010A3"
            self.parent.add_polyline(boundary_points+[boundary_points[0]],color,"history_boundary")
        

    def on_publish(self):
        if len(self.path_points)<1:
            self.ui.label_ok_erro.setText("当前任务不包含任何路径，请重新规划")
            self.ui.label_ok_erro.setStyleSheet("QLabel { color: red; }")
            return
        agent:sls_agent.MirrorsAgent = self.parent.mirror_agent
        mission_current_text = self.ui.comboBox_mission.currentText()
        uav_ugv_current_text = self.ui.comboBox_uav_ugv.currentText()
        plan_name = self.ui.comboBox_history_paths.currentText()
        plan_data = self.read_plan_fromjson(plan_name)
        if self.ui.checkBox_isUse_historyPlan.checkState() == Qt.CheckState.Unchecked:
            if self.current_method == "abline":
                self.path_points = [[point[1], point[0]] for point in self.click_points]
        longitudes = [point[0] for point in self.path_points]
        latitudes = [point[1] for point in self.path_points]
        boundary_latitudes = [point[0] for point in self.click_points]
        boundary_longitudes = [point[1] for point in self.click_points]
        if self.ui.checkBox_isUse_historyPlan.checkState() == Qt.CheckState.Checked:
            boundary_latitudes = [point[0] for point in plan_data["boundary_points"]]
            boundary_longitudes =  [point[1] for point in plan_data["boundary_points"]]
        if self.ui.checkBox_isSet_height.checkState() == Qt.CheckState.Unchecked:
            height = None
        elif self.ui.checkBox_isSet_height.checkState() == Qt.CheckState.Checked:
            height = float(self.ui.doubleSpinBox_mission_height.text())
        #组合并发送
        if self.current_method == "planner" or self.ui.checkBox_isUse_historyPlan.checkState() == Qt.CheckState.Checked:
            self.takeoffDict = {
                "missionsType": mission_current_text,
                "datasets":{
                    "latitudes":latitudes,
                    "longitudes":longitudes,
                    "rel_alt":height,
                    "boundaries":{
                        "latitudes":boundary_latitudes,
                        "longitudes":boundary_longitudes,
                    }
                }
            }
        if self.current_method == "abline":
            self.takeoffDict = {
                "missionsType": mission_current_text,
                "datasets":{
                    "latitudes":latitudes,
                    "longitudes":longitudes,
                    "rel_alt":height,
                }
            }
        agent.append_mission_to_schedule(uav_ugv_current_text,self.takeoffDict)
        agent.request_scheduleUpdate_missions_list(uav_ugv_current_text)
        
        save_dir = os.path.join(os.getcwd(), "clicked_points")
        os.makedirs(save_dir, exist_ok=True)
        timestr = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
        txt_path = os.path.join(save_dir, f"clicked_points_{timestr}.txt")

        with open(txt_path, "w", encoding="utf-8") as f:
            for lat, lon in self.click_points:
                f.write(f"{lat:.7f}, {lon:.7f}\n")

        self.ui.label_ok_erro.setText("任务发布成功")
        self.clearallset()
        self.parent.del_polyline("history_path")
        self.parent.del_polyline("history_boundary")
        self.use_history_path()
        self.close()

    def save_plan_tojson(self):  
        plan_name = self.ui.lineEdit_path_name.text()
        if plan_name == "":
            self.ui.label_planner_info.setText("请输入路径名")
            self.ui.label_planner_info.setStyleSheet("QLabel { color: red; }")
            return
        if self.check_plan_name_exists(plan_name):
            self.ui.label_planner_info.setText(f"路径名称 '{plan_name}' 已存在，请重新命名")
            self.ui.label_planner_info.setStyleSheet("QLabel { color: red; }")
            return  
        if len(self.path_points)<1:
            self.ui.label_planner_info.setText("当前路径不包含任何路径点，请重新规划")
            self.ui.label_planner_info.setStyleSheet("QLabel { color: red; }")
            return
        plan_data = {
            "plan_name": plan_name,
            "boundary_points":self.click_points,
            "path_points": self.path_points,
        }
        if not os.path.exists("pathsfile.json"):
            with open("pathsfile.json", "w", encoding="utf-8") as file:
                json.dump([], file)
        with open("pathsfile.json", "r", encoding="utf-8") as file:
            data = json.load(file)
        data.append(plan_data)
        with open("pathsfile.json", "w", encoding="utf-8") as file:
            json.dump(data, file, indent=4, ensure_ascii=False)
        self.ui.label_planner_info.setText("路径保存成功，可在历史路径栏查看")
        self.ui.label_planner_info.setStyleSheet("QLabel { color: black; }")
        self.ui.lineEdit_path_name.clear()
        self.init_history_plan_ui()

    def read_plan_fromjson(self, plan_name):

        try:
            with open("pathsfile.json", "r", encoding="utf-8") as file:
                data = json.load(file)
            for plan_data in data:
                if plan_data["plan_name"] == plan_name:
                    return plan_data 
            return None
        except FileNotFoundError:
            return None
        except json.JSONDecodeError:
            return None
        
    def del_history_plan(self):
        plan_name = self.ui.comboBox_history_paths.currentText()
        try:
            with open("pathsfile.json", "r", encoding="utf-8") as file:
                data = json.load(file)
        
            initial_length = len(data) 
            data = [plan_data for plan_data in data if plan_data["plan_name"] != plan_name]
        
            if len(data) == initial_length:
                self.ui.label_history_path_info.setText(f"未找到路径名称为 '{plan_name}' 的数据")
                return False
        
            with open("pathsfile.json", "w", encoding="utf-8") as file:
                json.dump(data, file, indent=4, ensure_ascii=False)
            self.ui.label_history_path_info.setText(f"成功删除路径名称为 '{plan_name}' 的数据")
            if self.ui.comboBox_history_boundaries.currentText() == plan_name:
                self.parent.del_polyline("boundary" )
                self.click_points = []
            self.init_history_plan_ui()
            return True
        except FileNotFoundError:
            self.ui.label_history_path_info.setText("文件不存在")
            return False
        except json.JSONDecodeError:
            self.ui.label_history_path_info.setText("JSON 文件格式错误")
            return False
        
        
    def check_plan_name_exists(self, plan_name):
        try:
            with open("pathsfile.json", "r", encoding="utf-8") as file:
                data = json.load(file)
            for plan_data in data:
                if plan_data["plan_name"] == plan_name:
                    return True
            return False
        except FileNotFoundError:
            return False
        except json.JSONDecodeError:
            return False

    def clearallset(self):
        self.parent.del_polyline("planed_path")
        self.parent.del_polyline("boundary")
        self.parent.del_sortedMarkers("boundary_point")
        self.parent.del_sortedMarkers("path_point")
        self.ui.label_planner_info.setText("请在地图点击鼠标右键选择任务区域")
        self.ui.label_planner_info.setStyleSheet("QLabel { color: black; }")
        self.ui.label_ok_erro.clear()
        self.click_points = []
        self.path_points = []
        self.marker_name = []

    def keyPressEvent(self, event):
        # 检测是否按下 ESC 键
        if event.key() == Qt.Key.Key_Escape:
            self.clearallset()
            self.parent.del_polyline("history_path")
            self.parent.del_polyline("history_boundary")
            self.menu.setEnabled(True)
            self.parent.notifyClass.remove_notify_Cordinate(self.on_click_point)
        # 记得调用父类的方法以确保其他键盘事件正常处理
        super().keyPressEvent(event)

    def closeEvent(self, event):
        # 当对话框关闭时，重新启用父窗口的按钮
        self.clearallset()
        self.parent.del_polyline("history_path")
        self.parent.del_polyline("history_boundary")
        self.parent.ui.uavPathPlan.setEnabled(True)
        self.parent.ui.ugvPathPlan.setEnabled(True)
        self.parent.ui.tools.setEnabled(True)
        self.parent.notifyClass.remove_notify_Cordinate(self.on_click_point)